/*
 * TCSS 422 Process Control Simulator
 * Group Money: Al McKenzie, Michael Pitts, Taylor Zielske
 */

/**
 * An Abstract Process which provides the basic operations a Process needs.
 * @author Michael Pitts
 * @version Dec 8, 2011
 */
public abstract class AbstractProcess implements Process {
	
	/** Stores the global next id which keeps Processes unique. */
	private static int NEXT_ID = 0;
	
	/** This Processes' ID. */
	private final int my_id;
	
	/** This Processes' name. */
	private final String my_name;
	
	/** This Processes; current Status. */
	private Status my_status;
	
	/** How many iterations are left for this process. */
	private int my_time_left;
	
	/**
	 * Creates a new Abstract Process with the given name.
	 * @param the_name is the name of the new Process.
	 * @param the_limit is how many iterations of this process to run.  If negative,
	 * the process will run forever.
	 */
	public AbstractProcess(final String the_name, final int the_limit) {
		my_name = the_name;
		my_id = NEXT_ID;
		NEXT_ID++;
		my_time_left = the_limit;
		my_status = Status.WAITING;
	}

	@Override public final int getID() {
		return my_id;
	}

	@Override public SysCall run() {
		my_time_left--;
		if (my_time_left <= 0) {
			return SysCall.DONE;
		}
		return SysCall.NOTHING;
	}

	@Override public final synchronized Status getStatus() {
		return my_status;
	}

	@Override public IODevice getWaitingOn() {
		return null;
	}

	@Override public final synchronized void setStatus(final Status the_status) {
		my_status = the_status;
	}
	
	@Override public final String toString() {
		return my_id + " (" + my_name + ")";
	}
	
	@Override public final boolean equals(final Object the_other) {
		return AbstractProcess.class.isInstance(the_other) && 
				((AbstractProcess) the_other).getID() == my_id;
	}
	
	@Override public final int hashCode() {
		return my_id;
	}

}
